#pragma once
#include "DXTypeDefs.h"

namespace Rendering {
class Element;
class Renderer
{
public:
	Renderer(void);
	virtual ~Renderer(void){}

	/// <summary>Gets the Direct3D device object.</summary>
	/// <value>The Direct3D device object.</value>
	ID3D11Device1Ptr Device()
	{ 
		return m_device;
	}

	/// <summary>Gets the Direct3D device context object.</summary>
	/// <value>The Direct3D device context object.</value>
	ID3D11DeviceContext1Ptr Context() { return m_context; }

	/// <summary>Gets the elements for the rendering.</summary>
	/// <value>The elements for the rendering.</value>
	std::vector<std::shared_ptr<Element>>& Elements() { return m_elements; }

	/// <summary>Gets/Sets the viewport for the renderer.</summary>
	/// <value>The viewport for the renderer.</value>
	D2D1_RECT_F Viewport() { return m_viewPort; }
	virtual void ViewPort(D2D1_RECT_F newViewPort) { UpdateViewport(newViewPort); }
		
	virtual void Initialize();

	virtual void CreateDeviceIndependentResources();
	virtual void CreateStaticResources();
	virtual void UpdateViewport(D2D1_RECT_F viewPort);
	virtual void UpdateRenderTargetSize(D2D1_SIZE_F renderTargetSize);

	virtual void Clear();
	virtual void Render(){};
	virtual void Present();
	virtual void TurnOnAlphaBlending();
	virtual void TurnOffAlphaBlending();

	void SetRenderTargetSize(SIZE size)
	{
		UpdateRenderTargetSize(m_renderTargetSize);
	}

protected:
	virtual void CreateSwapChain(IDXGIFactory2* dxgiFactory, DXGI_SWAP_CHAIN_DESC1& swapChainDesc) = 0;
	virtual void CreateRenderTargetResources();

protected:
	bool                       m_initialized;
	bool                       m_resourceInitialized;

	// Direct3D Objects
	ID3D11Device1Ptr           m_device;
	ID3D11DeviceContext1Ptr    m_context;
	IDXGISwapChain1Ptr         m_swapChain;
	ID3D11RenderTargetViewPtr  m_renderTargetView;
	ID3D11DepthStencilViewPtr  m_depthStencilView;
	ID3D11DepthStencilStatePtr m_depthStencilState;
	ID3D11RasterizerStatePtr   m_rasterState;

	ID3D11BlendStatePtr		   m_alphaEnableBlendingState;
	ID3D11BlendStatePtr		   m_alphaDisableBlendingState;

	D3D_FEATURE_LEVEL          m_featureLevel;
	D2D1_SIZE_F				   m_renderTargetSize;
	D2D1_RECT_F				   m_viewPort;
	int						   m_bufferCount;

	static float			   clearColor[4];

	std::vector< std::shared_ptr<Element> > m_elements;
};
}

